#include "State.h"

State::State()
{
	Parent = NULL;
	Target = NULL;
}

State::State(Bot *nParent, Entity *nTarget)
{
	Parent = nParent;
	Target = nTarget;
}

State::~State()
{

}

void State::SetTarget(Entity *nTarget)
{
	Target = nTarget;
}

void State::SetParent( Bot *nParent )
{
	Parent = nParent;
}

Seek::Seek() : State()
{
	Target = NULL;
}

Seek::Seek(Bot *nParent,  Entity *nTarget) : State(nParent, nTarget)
{

}

void Seek::SetTarget( Entity *nTarget)
{
	Target = nTarget;
}

void Seek::Enter( void )
{
	Parent->SetBehaviorID(1);
	return;
}

void Seek::Execute( float dt )
{
	//Old HILARIOUS code
	/*if(Parent && Target)
	{
		D3DXVECTOR3 TargetVector = Parent->BotShip->GetPosition() - Target->GetPosition();
		Parent->BotShip->SetAngles(TargetVector);
	}*/
	
	if(Parent && Target)
	{
		Parent->SetMaxThrottle(100);
		D3DXVECTOR3 TargetVector = Target->GetPosition() - Parent->BotShip->GetPosition();
		D3DXVec3Normalize(&TargetVector, &TargetVector);

		//Parent->BotShip->SetVelocity(Target->GetPosition() - Parent->BotShip->GetPosition());

		TargetVector = D3DXVECTOR3(-atan2(TargetVector.z, TargetVector.x) + DegToRad(90),
							                   -atan2(abs(TargetVector.z), -TargetVector.y) + DegToRad(90),
											   /*atan2(TargetVector.z, TargetVector.x)*/0);

		Parent->SetDesiredAngles(TargetVector);
#ifdef _DEBUG
		Parent->DebugVec = Target->GetPosition() - Parent->BotShip->GetPosition();
		/*if(Parent->DebugVec.y > 180)
			int k = 0;*/
#endif
		//Parent->BotShip->SetForwardThrottle(55);
	}
}

void Seek::Exit( void )
{
	return;
}

Flee::Flee() : State()
{
	Target = NULL;
}

Flee::Flee(Bot *nParent,  Entity *nTarget) : State(nParent, nTarget)
{

}

Flee::~Flee()
{

}

void Flee::SetTarget( Entity *nTarget)
{
	Target = nTarget;
}

void Flee::Enter( void )
{
	Parent->SetBehaviorID(2);
	return;
}

void Flee::Execute( float dt )
{
	/*if(Parent && Target)
	{
		D3DXVECTOR3 TargetVector = Parent->GetPosition() + Target->GetPosition();
		Parent->SetVelocity(TargetVector);
	}*/

	if(Parent && Target)
	{
		Parent->SetMaxThrottle(100);
		D3DXVECTOR3 TargetVector = Parent->BotShip->GetPosition() - Target->GetPosition();
		D3DXVec3Normalize(&TargetVector, &TargetVector);

		//Parent->BotShip->SetVelocity(Target->GetPosition() - Parent->BotShip->GetPosition());

		TargetVector = D3DXVECTOR3(-atan2(TargetVector.z, TargetVector.x) + DegToRad(90),
							                   -atan2(abs(TargetVector.z), -TargetVector.y) + DegToRad(90),
											   /*atan2(TargetVector.z, TargetVector.x)*/0);

		Parent->SetDesiredAngles(TargetVector);
#ifdef _DEBUG
		Parent->DebugVec = Target->GetPosition() - Parent->BotShip->GetPosition();
		/*if(Parent->DebugVec.y > 180)
			int k = 0;*/
#endif
		//Parent->BotShip->SetForwardThrottle(55);
	}
}

void Flee::Exit( void )
{
	return;
}

Wander::Wander() : State(), Direction(0,0,0) 
{
	Time = 0;
	NextDirectionChange = 0;
}

Wander::Wander(Bot *nParent, Entity *nTarget) : State(nParent, nTarget), Direction(0,0,0)
{
	srand(UINT(time(NULL)));
	Random->MersEngine.seed(UINT(clock()));
	Time = 0;
	NextDirectionChange = GenerateNewTime(UPPERTIMELIM);
}

Wander::~Wander()
{

}

void Wander::SetTarget( Entity *nTarget)
{
	//Do Nothing, wander needs no target
}

void Wander::Enter( void )
{
	Parent->SetBehaviorID(3);
	//Do nothing yet
}

void Wander::Execute( float dt )
{
	if(Parent)
	{
		Parent->SetMaxThrottle(25);
		Time += dt;

		if(Time >= NextDirectionChange)
		{
			if(!Parent->GetIsTurningOvertime())
			{
				Direction = GenerateNewDirection();
				Parent->SetDesiredAngles(Direction);
			}
			Time = 0;
			NextDirectionChange = GenerateNewTime(UPPERTIMELIM);
		}
	}
}

void Wander::Exit()
{

}

float Wander::GenerateNewTime( float upperLimit )
{
	float retVal = float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)) % int(upperLimit)+1);

	return retVal;
}

D3DXVECTOR3 Wander::GenerateNewDirection( void )
{
	UINT randomNumber = 0;
	D3DXVECTOR3 retVal(0,0,0);

	srand(UINT(time(NULL)));

	randomNumber = rand() % 18000;
	retVal.x = DegToRad(float(randomNumber % 360));

	randomNumber = rand() % 18000;
	retVal.y = DegToRad(float(randomNumber % 360));

	//randomNumber = rand() % 18000;
	//retVal.z = float(randomNumber % 360);
	retVal.z = 0;
	
	return retVal;
}